home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume8 / servercomm2 < prev    next >
Encoding:
Text File  |  1989-08-23  |  39.2 KB  |  1,344 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v08i013: Updated servercomm
  3. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  4. Reply-To: dinah@krebs.bcm.tmc.edu (Dinah Anderson)
  5.  
  6. Posting-number: Volume 8, Issue 13
  7. Submitted-by: dinah@krebs.bcm.tmc.edu (Dinah Anderson)
  8. Archive-name: servercomm2
  9.  
  10. Here is an updated version of servercomm. I modified the make file
  11. to not make the spool directories and modify the printcap since the
  12. make file wanted to do this everytime you installed the software. I
  13. also fixed the program to work correctly with the Sun pty's and a bridge
  14. comm. terminal server. The previous version did not work with SunOS 4.0 and
  15. postscript files properly.
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive, meaning:
  20. # 1. Remove everything above the #! /bin/sh line.
  21. # 2. Save the resulting text in a file.
  22. # 3. Execute the file with /bin/sh (not csh) to create the files:
  23. #    Makefile
  24. #    README
  25. #    example
  26. #    hello.ps
  27. #    servercomm.8l
  28. #    servercomm.c
  29. # This archive created: Wed Aug 23 12:04:23 1989
  30. export PATH; PATH=/bin:$PATH
  31. echo shar: extracting "'Makefile'" '(4422 characters)'
  32. if test -f 'Makefile'
  33. then
  34.     echo shar: will not over-write existing file "'Makefile'"
  35. else
  36. sed 's/^    X//' << \SHAR_EOF > 'Makefile'
  37.     X#
  38.     X# Wright State University Remote LaserWriter Kit
  39.     X# John Sloan <jsloan%SPOTS.Wright.EDU@@Relay.CS.NET>
  40.     X# $Revision: 1.3 $
  41.     X# $Date: 89/08/06 02:27:15 $
  42.     X#
  43.     X# Modified by Dinah Anderson <dinah@bcm.tmc.edu>
  44.     X# Baylor College of Medicine
  45.     X# 89/8/23
  46.     X#
  47.     X
  48.     X# C Compiler flags (if any)
  49.     XCFLAGS=-DBRIDGE
  50.     X
  51.     X# Printcap name of remote LaserWriter
  52.     XPRINTER=motc
  53.     X
  54.     X# Local LaserWriter spool directory (must differ from NEWSPOOLDIR)
  55.     XPSSPOOLDIR=/usr/spool/lpd/local
  56.     X
  57.     X# New remote LaserWriter spool directory (must differ from PSSPOOLDIR)
  58.     XNEWSPOOLDIR=/usr/spool/lpd/motc
  59.     X
  60.     X# Original Transcript software directory (must differ from NEWLIBDIR)
  61.     XPSLIBDIR=/usr/local/lib/ps
  62.     X
  63.     X# New remote Transcript filters directory (must differ from PSLIBDIR)
  64.     XNEWLIBDIR=/usr/motc
  65.     X
  66.     X# Network name of host computer handling spooling to communication server
  67.     X# This is the computer on which you are installing this software
  68.     XHOST="`hostname`"
  69.     X
  70.     X# Network name of host communications server
  71.     XSERVER=128.249.4.40
  72.     X
  73.     X# Port number for LaserWriter on host
  74.     XPORT=23
  75.     X
  76.     X# Master pseudo-terminal (typically /dev/ptyXX, where XX=[pqrs][0-f])
  77.     X# You may roll your own (as we do) with /etc/mknod
  78.     X# Owner should be daemon and mode should be 666
  79.     X# Device should not appear in /etc/ttys as login enabled (with getty)
  80.     XPTY=/dev/ptyr4
  81.     X
  82.     X# Slave pseudo-terminal (typically /dev/ttyXX)
  83.     X# You may roll your own (as we do) with /etc/mknod
  84.     X# Owner should be daemon and mode should be 666
  85.     X# Device should not appear in /etc/ttys as login enabled (with getty)
  86.     XTTY=/dev/ttyr4
  87.     X
  88.     X# Location of servercomm(8l) man page
  89.     XMANDIR=/usr/man/manl
  90.     X
  91.     X#########################################################################
  92.     X
  93.     Xall:    servercomm filters printcap printcap.remote 
  94.     X
  95.     Xinstall: all ${NEWLIBDIR}/servercomm ${MANDIR} servercomm.8l
  96.     X    cp /dev/null ${NEWLIBDIR}/${PRINTER}
  97.     X    cp servercomm.8l ${MANDIR}
  98.     X    chmod 644 ${MANDIR}/servercomm.8l
  99.     X
  100.     Xclean:
  101.     X    rm -if diffs printcap printcap.remote 
  102.     X
  103.     Xbackout: clean
  104.     X    rm -rif ${NEWSPOOLDIR} ${NEWLIBDIR}
  105.     X
  106.     Xservercomm:    servercomm.c
  107.     X    cc ${CFLAGS} -O -o servercomm servercomm.c
  108.     X
  109.     X${NEWLIBDIR}/servercomm: servercomm
  110.     X    strip servercomm
  111.     X    mv servercomm ${NEWLIBDIR}
  112.     X    chmod 755 ${NEWLIBDIR}/servercomm
  113.     X
  114.     Xtest:    debug hello.ps
  115.     X    debug -v -x -h ${SERVER} -p ${PORT} -t ${PTY} ${TTY} -f ${NEWLIBDIR}/pscomm -P ${PRINTER} -p psif /dev/tty < hello.ps
  116.     X#debug -v -x -h ${SERVER} -p ${PORT} -t ${PTY} ${TTY} -f ${PSLIBDIR}/pscomm -P ${PRINTER} -p psif /dev/tty < hello.ps
  117.     X    
  118.     Xdebug:    servercomm.c
  119.     X    cc ${CFLAGS} -g -DDEBUG -DDUMP -o debug servercomm.c
  120.     X
  121.     Xfilters: ${NEWLIBDIR} ${NEWLIBDIR}/psint.sh
  122.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psof
  123.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psif
  124.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psgf
  125.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psnf
  126.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/pstf
  127.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psrf
  128.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psvf
  129.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/pscf
  130.     X    ln ${NEWLIBDIR}/psint.sh ${NEWLIBDIR}/psdf
  131.     X
  132.     X${NEWLIBDIR}/psint.sh: ${PSLIBDIR}/psint.sh ${NEWLIBDIR} diffs
  133.     X    cp ${PSLIBDIR}/psint.sh ${NEWLIBDIR}
  134.     X    chmod 755 ${NEWLIBDIR}/psint.sh
  135.     X    patch ${NEWLIBDIR}/psint.sh diffs
  136.     X
  137.     X${NEWLIBDIR}:
  138.     X    mkdir ${NEWLIBDIR}
  139.     X    chmod 755 ${NEWLIBDIR}
  140.     X
  141.     Xdiffs:
  142.     X    echo "67c67,68" > diffs
  143.     X    echo "< comm=\"\$$PSCOMM -P \$$pname -p \$$prog -n \$$user -h \$$host \$$afile\"" >> diffs
  144.     X    echo "---" >> diffs
  145.     X    echo "> filter=\"\$$PSCOMM -P \$$pname -p \$$prog -n \$$user -h \$$host \$$afile\"" >> diffs
  146.     X    echo "> comm=\"servercomm -h ${SERVER} -p ${PORT} -t ${PTY} ${TTY} -f \$$filter\"" >> diffs
  147.     X
  148.     Xprintcap:
  149.     X    echo "${PRINTER}|LaserWriter on communication server ${SERVER} Port ${PORT}:\\" > printcap
  150.     X    echo "    :lp=${NEWLIBDIR}/${PRINTER}:sd=${NEWSPOOLDIR}:\\" >> printcap
  151.     X    echo "    :lf=${NEWSPOOLDIR}/lw-log:af=/usr/adm/lw.acct:\\" >> printcap
  152.     X    echo "    :mx#0:sf:sb:\\" >> printcap
  153.     X    echo "    :if=${NEWLIBDIR}/psif:\\" >> printcap
  154.     X    echo "    :of=${NEWLIBDIR}/psof:gf=${NEWLIBDIR}/psgf:\\" >> printcap
  155.     X    echo "    :nf=${NEWLIBDIR}/psnf:tf=${NEWLIBDIR}/pstf:\\" >> printcap
  156.     X    echo "    :rf=${NEWLIBDIR}/psrf:vf=${NEWLIBDIR}/psvf:\\" >> printcap
  157.     X    echo "    :cf=${NEWLIBDIR}/pscf:df=${NEWLIBDIR}/psdf:" >> printcap
  158.     X
  159.     X
  160.     Xprintcap.remote:
  161.     X    echo "${PRINTER}|Remote LaserWriter on Host ${HOST} communication server ${SERVER} Port ${PORT}:\\" > printcap.remote
  162.     X    echo "    :lp=:rm=${HOST}:rp=${PRINTER}:sd=${NEWSPOOLDIR}:" >> printcap.remote
  163.     X
  164.     Xsharfile:    README Makefile servercomm.8l servercomm.c hello.ps example
  165.     X    shar README Makefile servercomm.8l servercomm.c hello.ps example > sharfile
  166. SHAR_EOF
  167. if test 4422 -ne "`wc -c < 'Makefile'`"
  168. then
  169.     echo shar: error transmitting "'Makefile'" '(should have been 4422 characters)'
  170. fi
  171. fi # end of overwriting check
  172. echo shar: extracting "'README'" '(3390 characters)'
  173. if test -f 'README'
  174. then
  175.     echo shar: will not over-write existing file "'README'"
  176. else
  177. sed 's/^    X//' << \SHAR_EOF > 'README'
  178.     XManifest
  179.     X--------
  180.     X
  181.     XMakefile        installation makefile
  182.     Xservercomm.8l        manual page
  183.     Xservercomm.c        source code
  184.     Xhello.ps        Postscript "Hello, World" test file
  185.     Xexample            Sample output from configuration of 3com Comm Server
  186.     XREADME            This file
  187.     X
  188.     XTroubleshooting the connection to the server
  189.     X--------------------------------------------
  190.     X
  191.     X0) You may want to do this first, before doing the software installation.
  192.     X
  193.     X1) Kill the lpd daemon servicing your Laserwriter on the server, if
  194.     Xyou're troubleshooting after installing this kit.
  195.     X
  196.     X2) Provided you've already setup the port on the communications server
  197.     Xfor your Laserwriter, telnet to the port.
  198.     X
  199.     X3) If you get through the port to the Laserwriter, type the Postscript
  200.     Xcommand "executive" and see what the Laserwriter says. You should see a
  201.     X"PS>" prompt.  If the Laserwriter responds, then the physical
  202.     Xconnection at least is good. Type "quit" to get out of executive mode
  203.     Xon the Laserwriter.
  204.     X
  205.     X4) As usual, check the modes and ownerships of the directories and
  206.     Xespecially the pseudo master and slave terminals in /dev.
  207.     X
  208.     X5) Edit the Makefile, setting the various variables to meaningful
  209.     Xvalues. Then, "make test", and the Makefile will compile a version of
  210.     Xservercomm in the current directory with the debugging code in, and then
  211.     Xrun the debug version in verbose mode. Watch the output carefully and
  212.     Xlook for complaints from servercomm. You do not have to have the spool
  213.     Xdirectory, new print filters, or printcap built to do this step. You DO
  214.     Xhave to have the variables in the Makefile set appropriately for your
  215.     Xsite.
  216.     X
  217.     XInstallation Steps for Bridge Server and TRANSCRIPT
  218.     X---------------------------------------------------
  219.     X0) Use the Makefile as a model of what to do. The easiest thing is to
  220.     Xset the Makefile variables to meaningful values, and then use the
  221.     XMakefile just to make some ancillary files that you will find useful in
  222.     Xa moment. "make printcap" and  "make diffs" will not change
  223.     Xanything in your system, just make some files in the current
  224.     Xdirectory.
  225.     X
  226.     X1) Compile servercomm. (Type "make")
  227.     X
  228.     X2) Create a spool directory for the remote printer. 
  229.     X
  230.     X3) Create a new directory to hold the modified Transcript filter.
  231.     XAlthough there appears to be several filters, they are in fact all hard
  232.     Xlinks to the same shell script. Copy the Transcript filter psint.sh into
  233.     Xthis directory, make the indicated changes in "diffs" (they are quite
  234.     Xsmall), and establish all the requisite hard links. Since the filters
  235.     Xare all in fact sybolic links to a single file, the overhead in maintaining
  236.     Xa separate directory for every such remote printer is not high. Copy servercomm
  237.     Xto this new directory. (Type "make filters")
  238.     X
  239.     X4) Make up a printcap entry for the remote printer and install it in
  240.     Xthe /etc/printcap file. Use "printcap", produced by the Makefile, as an
  241.     Xexample. The filters should point to your new modified filters. The
  242.     Xspool area should point to your new spool directory. The device should
  243.     Xpoint to a null file (and not a real device), since servercomm handles
  244.     Xall the I/O.
  245.     X
  246.     X5) Set up the Bridge server by assigning an IP address to a port and
  247.     Xsetting the port parameters to those in the "example" file.
  248.     X
  249.     X6) Hook your Laserwriter up to the Bridge server to the port you just 
  250.     Xsetup.
  251.     X
  252.     X7) Try printing using the usual Berkeley lpr commands.  Look in lw-log
  253.     Xin the spool directory for errors. Under SunOS 4.0, you may find these
  254.     Xerrors in /usr/adm/lpd-errors.
  255. SHAR_EOF
  256. if test 3390 -ne "`wc -c < 'README'`"
  257. then
  258.     echo shar: error transmitting "'README'" '(should have been 3390 characters)'
  259. fi
  260. fi # end of overwriting check
  261. echo shar: extracting "'example'" '(1026 characters)'
  262. if test -f 'example'
  263. then
  264.     echo shar: will not over-write existing file "'example'"
  265. else
  266. sed 's/^    X//' << \SHAR_EOF > 'example'
  267.     X 
  268.     Xcs/1t# sh (!63) dp
  269.     XDefaultParameters  for PortId !63
  270.     X...................Port Transmission and VTP Characteristics...................
  271.     XAUToDisconnect = 60 AUtoLogoff = OFF    BUffersize = 82
  272.     XDeVice = ( Host, Glass, DeFault )       PermanentVC = ""
  273.     X.........................Port Physical Characteristics.........................
  274.     XBAud = 9600         BSPad = None        CRPad = None        FFPad = None
  275.     XLFPad = None        TabPad = None       DataBits = 7        DUplex = Full
  276.     XLinePRotocol = ASynchronous             PARIty = AutoParity StopBits = 1
  277.     XUseDCDout = ( AlwaysAssert, NoToggle )  UseDTRin = AsDTR (by DTE)
  278.     X.................Session Transmission and VTP Characteristics..................
  279.     XBReakAction = IGnore                    DIsconnectAction = None
  280.     XDataForward = None  ECHOData = OFF
  281.     XECHOMask = ( AlphaNum, CR, Term, Punct )                    NetAScii = UseLF
  282.     XFlowControlFrom = ( Xon_Xoff )          FlowControlTo = ( Xon_Xoff )
  283.     XIdleTimer = 2       LongBReakAction = IGnore                XOFF = ^S
  284.     XXON = ^Q
  285.     Xcs/1t# 
  286. SHAR_EOF
  287. if test 1026 -ne "`wc -c < 'example'`"
  288. then
  289.     echo shar: error transmitting "'example'" '(should have been 1026 characters)'
  290. fi
  291. fi # end of overwriting check
  292. echo shar: extracting "'hello.ps'" '(4967 characters)'
  293. if test -f 'hello.ps'
  294. then
  295.     echo shar: will not over-write existing file "'hello.ps'"
  296. else
  297. sed 's/^    X//' << \SHAR_EOF > 'hello.ps'
  298.     X%!PS-Adobe-1.0
  299.     X%%Creator: odin:jsloan (John Sloan,407 Fawcett,2987,5134268082)
  300.     X%%Title: stdin
  301.     X%%CreationDate: Tue Jun 21 11:41:28 1988
  302.     X%%DocumentFonts: Times-Roman Times-Italic Times-Bold Symbol Times-Roman
  303.     X%%Pages: (atend)
  304.     X%%EndComments
  305.     X% lib/pscat.pro -- prolog for pscat (troff) files
  306.     X% Copyright (C) 1985 Adobe Systems, Inc.
  307.     X% Added defs for Manual Feed 
  308.     Xsave /pscatsave exch def
  309.     X/$pscat 50 dict def
  310.     X$pscat begin
  311.     X/fm [1 0 0 1 0 0] def
  312.     X/xo 0 def /yo 0 def
  313.     X/M /moveto load def
  314.     X/R /show load def
  315.     X/S {exch currentpoint exch pop moveto show}def
  316.     X/T {exch currentpoint pop exch moveto show}def
  317.     X/U {3 1 roll moveto show}def
  318.     X/siz 0 def
  319.     X/font 0 def
  320.     X/Z {/siz exch def SF}def
  321.     X/F {/font exch def SF}def
  322.     X/SF{font 0 ne
  323.     X    {catfonts font 1 sub get fm 0 siz put fm 3 siz neg put 
  324.     X     fm makefont setfont}if}def
  325.     X/BP{save/catsv exch def 0 792 translate 72 432 div dup neg scale 
  326.     X  xo yo translate 0 0 moveto}def
  327.     X/BPL{save/catsv exch def 72 8.25 mul 792 translate -90 rotate
  328.     X  72 432 div dup neg scale xo yo translate 0 0 moveto}def
  329.     X/EP{catsv restore showpage}def
  330.     X/SetStTime{statusdict /manualfeedtimeout 120 put} def
  331.     X/SetStatus{statusdict /manualfeed true put
  332.     X   statusdict /product get (LaserWriter) eq 
  333.     X   {version (23.0) eq  % Don't redefine EP if printer is not "Classic LW"
  334.     X     {/EP {catsv restore
  335.     X     {statusdict /printerstatus get exec 16#22000000 and 0 eq{exit}if}loop
  336.     X     showpage}def}if }if}def
  337.     X% definitions for PPROC callback functions
  338.     X% each PPROC is called with the following number on the stack:
  339.     X% pointsize charcode railmag pswidth pschar x y wid
  340.     X/$pprocs 50 dict def
  341.     X/fractm [.65 0 0 .6 0 0] def
  342.     X% fractions
  343.     X/PS1{gsave $pprocs begin
  344.     X    /wid exch def pop pop pop pop pop /ch exch def /size exch def
  345.     X    /pair $pprocs ch get def /cf currentfont def
  346.     X    cf fractm makefont setfont
  347.     X    0 .3 size mul 6 mul 2 copy neg rmoveto pair 0 get show rmoveto
  348.     X    currentfont cf setfont (\244) show setfont
  349.     X    pair 1 get show grestore wid .06 div 0 rmoveto end}def
  350.     X$pprocs begin
  351.     X8#34 [(1)(4)] def
  352.     X8#36 [(1)(2)] def
  353.     X8#46 [(3)(4)] def
  354.     Xend
  355.     X% boxes
  356.     X/PS2{gsave /wid exch def pop pop /char exch def pop pop pop /size exch def
  357.     X    /len size 3.5 mul def % length of a side
  358.     X    len 0 rlineto 0 len neg rlineto len neg 0 rlineto closepath
  359.     X    char 3 eq {fill}{size 5 mul .07 mul setlinewidth stroke}ifelse
  360.     X    grestore wid .06 div 0 rmoveto}def
  361.     X/PS3/PS2 load def        % boxes are the same...
  362.     X% circle
  363.     X/PS4{gsave /wid exch def pop pop pop pop pop pop /size exch def
  364.     X    wid .8333 mul size 2.5 mul neg rmoveto currentpoint    % center
  365.     X    newpath size 1.8 mul 0 360 arc size .2 mul setlinewidth stroke
  366.     X    grestore wid .06 div 0 rmoveto}def
  367.     X/bb{$pprocs begin /wid exch def pop pop pop pop pop pop /size exch 6 mul def
  368.     X    /s2 size 2 div def /s4 size 4 div def gsave 
  369.     X    currentpoint newpath transform round exch round exch itransform translate
  370.     X    size 16 div setlinewidth 2 setlinejoin 0 setgray}def
  371.     X$pprocs begin
  372.     X/mrr{moveto rlineto rlineto}def
  373.     X/be{stroke grestore wid .06 div 0 rmoveto end}def
  374.     Xend
  375.     X% leftfloor
  376.     X/PS6 {bb s4 0 0 size s4 size -.8 mul mrr be}def
  377.     X% rightfloor
  378.     X/PS7 {bb s4 neg 0 0 size s4 size -.8 mul mrr be}def
  379.     X% leftceil
  380.     X/PS8 {bb s4 0 0 size neg s4 size .2 mul mrr be}def
  381.     X% rightceil
  382.     X/PS9 {bb s4 neg 0 0 size neg s4 size .2 mul mrr be}def
  383.     X% boldvert
  384.     X/PS5 {bb 0 0 0 size neg s4 size .2 mul mrr be}def
  385.     X% box rule
  386.     X/PS32 {bb /sw size 24 div def sw 2 div size 4.5 div moveto
  387.     X       0 size neg rlineto sw setlinewidth be}def
  388.     X% rule (roman, bold and italic)
  389.     X/PS16 {gsave $pprocs begin
  390.     X    /wid exch def pop pop pop pop pop pop /size exch 6 mul def
  391.     X    /sw size 14 div def currentpoint exch sw 2 div sub exch
  392.     X    newpath transform round exch round exch itransform translate
  393.     X    0 0 moveto size 2 div 0 rlineto sw setlinewidth be}def
  394.     X% lefttopcurl    
  395.     X/PS20 {bb s4 size .2 mul moveto 0 size -.55 mul rlineto currentpoint 
  396.     X    pop size -.8 mul 2 copy exch s4 add exch s4 arcto pop pop pop pop be}def
  397.     X% leftbotcurl
  398.     X/PS21 {bb s4 size -.8 mul moveto 0 size .55 mul rlineto currentpoint 
  399.     X    pop size .2 mul 2 copy exch s4 add exch s4 arcto pop pop pop pop be}def
  400.     X% righttopcurl
  401.     X/PS22 {bb s4 size .2 mul moveto 0 size -.55 mul rlineto currentpoint
  402.     X     pop size -.8 mul 2 copy exch s4 sub exch s4 arcto pop pop pop pop be}def
  403.     X% rightbotcurl
  404.     X/PS23 {bb s4 size -.8 mul moveto 0 size .55 mul rlineto currentpoint
  405.     X     pop size .2 mul 2 copy exch s4 sub exch s4 arcto pop pop pop pop be}def
  406.     X% rightmidcurl
  407.     X/PS25 {bb /s3 size -.3 mul def s4 size -.8 mul moveto s4 s3 s2 s3
  408.     X    s4 arcto pop pop size add s4 s3 4 2 roll
  409.     X    s4 arcto pop pop pop pop s4 size .2 mul lineto be}def
  410.     X% leftmidcurl
  411.     X/PS24 {bb /s3 size -.3 mul def s4 size -.8 mul moveto s4 s3 0 s3
  412.     X    s4 arcto pop pop size add s4 s3 4 2 roll s4 arcto pop pop pop pop 
  413.     X    s4 size .2 mul lineto be}def
  414.     X/catfonts [
  415.     X    /Times-Roman findfont
  416.     X    /Times-Italic findfont
  417.     X    /Times-Bold findfont
  418.     X    /Symbol findfont
  419.     X    /Times-Roman findfont
  420.     X    ] def
  421.     X%%EndProlog
  422.     X%%Page: ? 1
  423.     XBP
  424.     X1 F
  425.     X60 Z
  426.     X432 165(Hello,)U
  427.     X601(World!)S
  428.     XEP
  429.     X%%Trailer
  430.     Xpscatsave end restore
  431.     X%%Pages: 1
  432. SHAR_EOF
  433. if test 4967 -ne "`wc -c < 'hello.ps'`"
  434. then
  435.     echo shar: error transmitting "'hello.ps'" '(should have been 4967 characters)'
  436. fi
  437. fi # end of overwriting check
  438. echo shar: extracting "'servercomm.8l'" '(4271 characters)'
  439. if test -f 'servercomm.8l'
  440. then
  441.     echo shar: will not over-write existing file "'servercomm.8l'"
  442. else
  443. sed 's/^    X//' << \SHAR_EOF > 'servercomm.8l'
  444.     X.TH SERVERCOMM 8 "8 JULY 1989"
  445.     X\" $Header$
  446.     X.ds TS T\s-2RAN\s+2S\s-2CRIPT\s+2
  447.     X.SH NAME
  448.     Xservercomm \- spool to a printer on a terminal server
  449.     X.SH SYNOPSIS
  450.     X.B servercomm
  451.     X[ \fB\-v\fR ]
  452.     X[ \fB\-x\fR ]
  453.     X[ \fB\-d\fI device\fR ]
  454.     X[ \fB\-h\fI host\fR [ \fB\-p\fI port\fR ] ]
  455.     X[ \fB\-t\fI ptydevice ttydevice\fR ]
  456.     X[ \fB\-f\fI filter\fR ]
  457.     X.SH DESCRIPTION
  458.     X.I servercomm
  459.     Xis an program that provides an interface between a typical Berkeley
  460.     X.I lpd
  461.     Xfilter (such as those provided in the Adobe \*(TS package) and
  462.     Xa printer (such as a LaserWriter) connected to a serial port on a
  463.     Xterminal server manufactured by 3com (Bridge), cisco systems, or
  464.     XXylogics (Annex). 
  465.     X.I Servercomm
  466.     Xmakes a TCP/IP TELNET connection to the specified serial port of the
  467.     Xspecified terminal server. It then forks and execs the normal filter
  468.     X(as specified).
  469.     XSince filters expect to talk to a physical device, a /dev/tty??, so
  470.     X.I servercomm
  471.     Xobliges by communicating with filters
  472.     Xthrough the master and slave portions of a network pseudo-terminal pair,
  473.     X/dev/pty?? and /dev/tty??. 
  474.     X.I Servercomm
  475.     Xhandles the interchange of data between the pseudo-terminal and the
  476.     Xcommunications server. 
  477.     X.I Lpd
  478.     Xand any filters behave as if they were communicating with a directly-attached
  479.     Xprinter.
  480.     X.SH OPTIONS
  481.     X.LP
  482.     X.IP "\fB\-v\fR"
  483.     XTurn on the debugging output to stderr, if the option was enabled at
  484.     Xcompile time through the use of the -DDEBUG cc switch.
  485.     X.IP "\fB\-x\fR"
  486.     XTurn on the dump output to stderr, if the option was enabled at compile
  487.     Xtime through the use of the -DDUMP cc switch.
  488.     X.IP "\fB\-d\fI device\fR"
  489.     XSpecify a device, such as /dev/lp, to use instead of the terminal server.
  490.     XThis is useful for debugging the filter with a hardwired printer. Omitted
  491.     Xif the \fB\-h\fR switch is used.
  492.     X.IP "\fB\-h\fI host\fR"
  493.     XSpecify the host name of the terminal server [or port on a terminal server]
  494.     Xthat the printer is attached to.
  495.     XOmitted if the \fB\-d\fR switch is used.
  496.     X.IP "\fB\-p\fI port\fR"
  497.     XSpecify the number of the serial port that the printer is attached
  498.     Xto. Omitted if the \fB\-d\fR switch is used. This switch is unneeded with
  499.     Xthe 3com or cisco terminal servers.
  500.     X.IP "\fB\-t\fI ptydevice ttydevice\fR"
  501.     XIndicate the master-slave pseudo-terminal pair to be used to communicate
  502.     Xwith the filter. The tty name could be intuited from the pty name, provided
  503.     Xthe standard names are used, but the user should be able to name the
  504.     Xpair something else, like /dev/plp and /dev/tlp.
  505.     X.IP "\fB\-f\fI filter\fR"
  506.     XProvide the complete command line for the filter to be invoked.
  507.     XTypically, this is 
  508.     X.I pscomm
  509.     Xfrom the \*(TS package, but it could be something else.
  510.     X.SH "NOTES for \*(TS "
  511.     XBriefly, the Berkeley line printer daemon, 
  512.     X.I lpd,
  513.     Xinvokes filters to handle communications with a printer attached to a
  514.     Xserial port on the host computer. If these filters are modified to start
  515.     X.I servercomm
  516.     Xinstead of calling the usual communications filter, 
  517.     X.I pscomm,
  518.     Xthen
  519.     X.I servercomm 
  520.     Xwill initialize the connection and start
  521.     X.I pscomm
  522.     Xto output the information.
  523.     X.br
  524.     XTo install
  525.     X.I servercomm,
  526.     Xcopy it in the the directory where
  527.     X.I pscomm
  528.     Xis located. Make a copy of the 
  529.     X.I psint.sh
  530.     Xshell script and edit it to make the following changes.
  531.     X.br
  532.     XChange the line the begins
  533.     X.B comm=
  534.     Xto begin with
  535.     X.B filter=
  536.     Xand then add this line:
  537.     X.br
  538.     Xcomm=servercomm -h
  539.     X.B hostname
  540.     X-p
  541.     X.B portid
  542.     X-t
  543.     X.B tty-names
  544.     X-f $filter
  545.     X.br
  546.     X.sp
  547.     X.B hostname,
  548.     X.B portid,
  549.     Xand
  550.     X.B psudo-tty-name
  551.     Xare described above.
  552.     XIf you replace the 
  553.     X.I psint.sh
  554.     Xscript with this modified one, then your changes are complete. However, if
  555.     Xyou have more than one printer, you will need a version of
  556.     X.I psint.sh
  557.     Xfor each one.
  558.     X.SH FILES
  559.     X.nf
  560.     X/etc/printcap    printer capabilities data base
  561.     X/usr/lib/lpd*    line printer daemons
  562.     X/usr/spool/*    directories used for spooling
  563.     X.fi
  564.     X.SH "SEE ALSO"
  565.     Xprintcap(5),
  566.     Xlpc(8),
  567.     Xlpd(8),
  568.     Xpscomm(8),
  569.     Xpsif(8)
  570.     X.SH DIAGNOSTICS
  571.     XThere are many possible fatal diagnostic messages. Each indicates which
  572.     Xroutine in 
  573.     X.I servercomm
  574.     Xhad the fatal error. In most cases,
  575.     X.I servercomm
  576.     Xreturns an LPD_ABORT code to 
  577.     X.I lpd.
  578.     XIf the specified filter (typically 
  579.     X.I pscomm
  580.     X) fails, 
  581.     X.I servercomm
  582.     Xreturns the exit code of the filter to
  583.     X.I lpd.
  584.     X.SH NOTES
  585.     X\*(TS is a trademark of Adobe Systems Incorporated.
  586.     X.br
  587.     XAnnex is a trademark of Xylogics Incorporated.
  588.     X.br
  589.     XLaserWriter is a trademark of Apple Computer.
  590. SHAR_EOF
  591. if test 4271 -ne "`wc -c < 'servercomm.8l'`"
  592. then
  593.     echo shar: error transmitting "'servercomm.8l'" '(should have been 4271 characters)'
  594. fi
  595. fi # end of overwriting check
  596. echo shar: extracting "'servercomm.c'" '(16356 characters)'
  597. if test -f 'servercomm.c'
  598. then
  599.     echo shar: will not over-write existing file "'servercomm.c'"
  600. else
  601. sed 's/^    X//' << \SHAR_EOF > 'servercomm.c'
  602.     X/*
  603.     X**    S E R V E R C O M M
  604.     X**
  605.     X**    Title:            servercomm (formerly annexf)
  606.     X**    Original Author:    John Sloan (internet: jsloan@SPOTS.Wright.Edu)
  607.     X**    System:            SunOS 
  608.     X**    Language:        C
  609.     X**    Date:            April 1988
  610.     X**    Abstract
  611.     X**
  612.     X**    Servercomm is a filter for the Berkeley spooler daemon that
  613.     X**    establishes a bidirectional TCP/IP/TELNET connection to
  614.     X**    a serial port on an terminal server made by popular makers
  615.     X**    so that printouts can be spooled to a serial printer connected
  616.     X**    to the server. It is intended to be used with an Apple
  617.     X**    Laserwriter and the Adobe Transcript package, but could
  618.     X**    be used for other things as well. It can also be configured
  619.     X**    at run time to talk to a /dev device instead of the terminal server
  620.     X++
  621.     X++    Modified by Jim Warner to work with the service listener
  622.     X++    port on Bridge Communications terminal servers.  The dialog
  623.     X++    in handshake() is unnecessary.  The "port" number was the physical
  624.     X++    connector on the back of the annex.  For Bridge (and Cisco, I bet)
  625.     X++    this is the tcp-port number to use instead of telnet=23.  For
  626.     X++    Bridge, we're going to need an IP address per printer.
  627.     X++                        Jan 2 1989
  628.     X==
  629.     X==    Modified by Dinah Anderson <dinah@bcm.tmc.edu> to use the 
  630.     X==    sys/termios.h data structure instead of the sys/ioctl.h.
  631.     X==    Also set the ptys characteristics explicitly since most postscript
  632.     X==    files would not print. We tested this using a Bridge server.
  633.     X==    8/23/89.
  634.     X**
  635.     X**    Disclaimer
  636.     X**
  637.     X**    This software is supplied as is, and no warranty is expressed or
  638.     X**    implied as to its correctness, functionality, or suitability
  639.     X**    for any application, anywhere, at anytime, by anyone.
  640.     X**
  641.     X**    Acknowledgements
  642.     X**
  643.     X**    Much of this code was inspired by telnet.c from UCB and aprint.c
  644.     X**    from Encore Computer. No code borrowed, but a lot of questions
  645.     X**    were answered by perusing these examples. Also, many thanks to
  646.     X**    Ken Yap <ken@cs.rochester.edu>, who suggested using a pty/tty
  647.     X**    pair to communicate with pscomm. I was working on that when I
  648.     X**    received his email, and it was encouraging to hear someone else
  649.     X**    that thought it should work.
  650.     X**
  651.     X**    Compile Time Flags
  652.     X**
  653.     X**    DEBUG        Compiles in debugging code to make
  654.     X**            useful remarks on stderr. Use the
  655.     X**            -v run time flag to activate.
  656.     X**
  657.     X**    DUMP        Compiles in code to dump data to stderr
  658.     X**            as it's being processed. Very verbose,
  659.     X**            but useful in debugging. Use the -x run
  660.     X**            time flag to activate.
  661.     X**
  662.     X**    BRIDGE        Compiles in code to support CISCO or BRIDGE
  663.     X**            communications servers.
  664.     X**
  665.     X*/
  666.     X/*
  667.     X**    To do:
  668.     X**        The pseudottys should not have to be specified. The program
  669.     X**        should find the first available ones and use them.
  670.     X**
  671.     X*/
  672.     X#include <stdio.h>
  673.     X#include <sys/types.h>
  674.     X#include <sys/file.h>
  675.     X#include <sys/termios.h>
  676.     X#include <ctype.h>
  677.     X#include <errno.h>
  678.     X#include <fcntl.h>
  679.     X#include <setjmp.h>
  680.     X#include <signal.h>
  681.     X#include <netdb.h>
  682.     X#include <netinet/in.h>
  683.     X#define    TELOPTS
  684.     X#include <arpa/telnet.h>
  685.     X#include <arpa/inet.h>
  686.     X#include <sys/socket.h>
  687.     X#include <sys/wait.h>
  688.     X#include <strings.h>
  689.     X
  690.     X#define LPD_OK 0        /* lpd filter exit codes */
  691.     X#define LPD_RETRY 1
  692.     X#define LPD_ABORT 2
  693.     X#define BUFFER 512        /* spooler buffer size in bytes */
  694.     X#define CR '\015'
  695.     X#define PROMPT ':'
  696.     X
  697.     X#ifdef DEBUG
  698.     X#define DPRINTF(s)    if (debugon) fprintf s
  699.     X#else
  700.     X#define DPRINTF(s)
  701.     X#endif
  702.     X
  703.     X/*
  704.     X**    Identification
  705.     X*/
  706.     Xstatic char id[]="$Header: /home/crick/vpit/sob/src/servercomm/RCS/servercomm.c,v 1.1 89/08/06 00:10:36 sob Exp Locker: sob $";
  707.     X
  708.     X/*
  709.     X**    Must be static (used by network code).
  710.     X*/
  711.     Xstruct servent *srvc;
  712.     Xstruct hostent *host;
  713.     Xstruct sockaddr_in sock;
  714.     Xstruct sockaddr dev;
  715.     Xstruct termios ttycb;
  716.     Xjmp_buf context;
  717.     X
  718.     X/*
  719.     X**    Must be global (used by interrupt service routines).
  720.     X*/
  721.     X#ifndef errno
  722.     Xextern int errno;    /* warner: not needed for Sun OS */
  723.     X#endif
  724.     Xchar *pgmname;
  725.     Xint filterpid,prodpid,conspid;
  726.     Xint netfd,ptyfd,ttyfd;
  727.     Xint debugon,dumpon;
  728.     X
  729.     Xvoid setup(),cleanup(),handshake(),trigger(),rendezvous();
  730.     Xvoid spool(),transmit(),usage(),bailout(),fatal();
  731.     Xvoid lost(),interrupted(),finished();
  732.     X#ifdef DEBUG
  733.     Xvoid pargs();
  734.     X#endif
  735.     X
  736.     Xmain(argc,argv)
  737.     Xint argc;
  738.     Xchar *argv[];
  739.     X    {
  740.     X    int nargc,rc;
  741.     X    char *host,*port,*device,*filter,*pty,*tty,**nargv;
  742.     X
  743.     X    pgmname=rindex(argv[0],'/');
  744.     X    pgmname=pgmname?pgmname+1:argv[0];
  745.     X    setup(argc,argv,&debugon,&dumpon,&host,&port,&device,&pty,&tty,&filter,&nargc,&nargv);
  746.     X    filterpid=0;
  747.     X    prodpid=0;
  748.     X    conspid=0;
  749.     X    if (pty!=NULL)
  750.     X        {
  751.     X        ptyfd=acquire(pty);
  752.     X        ttyfd=acquire(tty);
  753.     X        if ((rc=ioctl(ttyfd,TCGETS,&ttycb))<0)
  754.     X            fatal(rc,"main ioctl getp failed",LPD_ABORT);
  755.     X        ttycb.c_cflag = (B9600 | CS7 | CREAD );
  756.     X        ttycb.c_oflag = (OPOST | OCRNL );
  757.     X        ttycb.c_iflag = (ISTRIP );
  758.     X        ttycb.c_lflag = (0 );
  759.     X        if ((rc=ioctl(ttyfd,TCSETS,&ttycb))<0)
  760.     X            fatal(rc,"main ioctl setp failed",LPD_ABORT);
  761.     X        }
  762.     X    else
  763.     X        ptyfd=0;
  764.     X    if (host!=NULL)
  765.     X        netfd=establish(host,port);
  766.     X    else if (device!=NULL)
  767.     X        netfd=acquire(device);
  768.     X    else
  769.     X        usage(0);
  770.     X    if (rc=setjmp(context))
  771.     X        bailout(rc);
  772.     X    if (port!=NULL)
  773.     X        handshake(netfd,port);
  774.     X    if (filter!=NULL)
  775.     X        {
  776.     X        /*
  777.     X        ** Fork off producer and consumer processes
  778.     X        ** ahead of the filter so that they are ready
  779.     X        ** to handle the filter's I/O immediately. This
  780.     X        ** scheme is process intensive (makes several
  781.     X        ** processes) but is simpler than using non-blocking
  782.     X        ** I/O, which was the original implementation.
  783.     X        */
  784.     X        spool(netfd,ptyfd,&prodpid,&conspid);
  785.     X        filterpid=attach(filter,nargc,nargv,ttyfd);
  786.     X        /*
  787.     X        ** Don't let children inherit our interrupt
  788.     X        ** service routines. This naively assumes that
  789.     X        ** nothing interesting will happen prior to now.
  790.     X        */
  791.     X        signal(SIGPIPE,lost);
  792.     X        signal(SIGINT,interrupted);
  793.     X        /*
  794.     X        ** Wait for something interesting to happen.
  795.     X        */
  796.     X        rendezvous(filterpid,prodpid,conspid);
  797.     X        DPRINTF((stderr,"%s: main complete\n",pgmname));
  798.     X        exit(LPD_OK);
  799.     X        }
  800.     X    }
  801.     X
  802.     X/*
  803.     X**    Setup: parses argument list.
  804.     X*/
  805.     Xvoid
  806.     Xsetup(argc,argv,dbgon,dmpon,host,port,device,pty,tty,filter,nargc,nargv)
  807.     Xint argc,*dbgon,*dmpon,*nargc;
  808.     Xchar *argv[],**host,**port,**device,**pty,**tty,**filter,***nargv;
  809.     X    {
  810.     X
  811.     X    *dbgon=0;
  812.     X    *dmpon=0;
  813.     X    *host=NULL;
  814.     X    *port=NULL;
  815.     X    *device=NULL;
  816.     X    *pty=NULL;
  817.     X    *tty=NULL;
  818.     X    *filter=NULL;
  819.     X    *nargc=0;
  820.     X    *nargv=NULL;
  821.     X    while (argc>0)
  822.     X        {
  823.     X        if (argv[0][0]=='-')
  824.     X            {
  825.     X            switch (argv[0][1])
  826.     X                {
  827.     X            case 'v':
  828.     X                *dbgon=1;
  829.     X                DPRINTF((stderr,"%s: debug on\n",pgmname));
  830.     X                break;
  831.     X            case 'x':
  832.     X                *dmpon=1;
  833.     X                DPRINTF((stderr,"%s: dump on\n",pgmname));
  834.     X                break;
  835.     X            case 'h':
  836.     X                usage(--argc);
  837.     X                *host=(*++argv);
  838.     X                DPRINTF((stderr,"%s: setup host=%s\n",pgmname,*host));
  839.     X                break;
  840.     X            case 'p':
  841.     X                usage(--argc);
  842.     X                *port=(*++argv);
  843.     X                DPRINTF((stderr,"%s: setup port=%s\n",pgmname,*port));
  844.     X                break;
  845.     X            case 'd':
  846.     X                usage(--argc);
  847.     X                *device=(*++argv);
  848.     X                DPRINTF((stderr,"%s: setup device=%s\n",pgmname,*device));
  849.     X                break;
  850.     X            case 't':
  851.     X                usage(--argc);
  852.     X                *pty=(*++argv);
  853.     X                usage(--argc);
  854.     X                *tty=(*++argv);
  855.     X                DPRINTF((stderr,"%s: setup pty=%s, tty=%s\n",pgmname,*pty,*tty));
  856.     X                break;
  857.     X            case 'f':
  858.     X                usage(--argc);
  859.     X                *filter=(*++argv);
  860.     X                *nargv=argv;
  861.     X                *nargc=argc;
  862.     X                argc=0;
  863.     X                DPRINTF((stderr,"%s: setup filter=%s, argc=%d\n",pgmname,*filter,*nargc));
  864.     X                break;
  865.     X            default:
  866.     X                usage(0);
  867.     X                }
  868.     X            }
  869.     X        argv++;
  870.     X        argc--;
  871.     X        }
  872.     X    }
  873.     X
  874.     X/*
  875.     X**    Cleanup: Shutdown child processes, close files, do anything else
  876.     X**    necessary to gracefully complete in the event of an error.
  877.     X*/
  878.     Xvoid
  879.     Xcleanup()
  880.     X    {
  881.     X    /*
  882.     X    ** Filter may not have been started up yet.
  883.     X    */
  884.     X    if (filterpid)
  885.     X        {
  886.     X        kill(filterpid,SIGTERM);
  887.     X        DPRINTF((stderr,"%s: cleanup killed filter %d\n",pgmname,filterpid));
  888.     X        }
  889.     X    /*
  890.     X    ** Producer may not have been started up yet.
  891.     X    */
  892.     X    if (prodpid)
  893.     X        {
  894.     X        kill(prodpid,SIGTERM);
  895.     X        DPRINTF((stderr,"%s: cleanup killed spooler %d\n",pgmname,prodpid));
  896.     X        }
  897.     X    /*
  898.     X    ** Consumer may not have been started up yet.
  899.     X    */
  900.     X    if (conspid)
  901.     X        {
  902.     X        kill(conspid,SIGTERM);
  903.     X        DPRINTF((stderr,"%s: cleanup killed spooler %d\n",pgmname,conspid));
  904.     X        }
  905.     X    /*
  906.     X    ** These may be already closed, in which case close returns an
  907.     X    ** error we can safely ignore.
  908.     X    */
  909.     X    close(ptyfd);
  910.     X    close(ttyfd);
  911.     X    close(netfd);
  912.     X    }
  913.     X
  914.     X/*
  915.     X**    Establish: Given a host name or an IP address, establish a real
  916.     X**    time TCP/IP/TELNET connection to the specified Annex.
  917.     X*/
  918.     Xint
  919.     Xestablish(hostname,port)
  920.     Xchar *hostname, *port;
  921.     X    {
  922.     X    char *name;
  923.     X    int rc,netfd;
  924.     X
  925.     X    if ((srvc=getservbyname("telnet","tcp"))==0)
  926.     X        fatal(srvc,"establish getservbyname failed",LPD_ABORT);
  927.     X    if (host=gethostbyname(hostname))
  928.     X        {
  929.     X        /*
  930.     X        ** hostname is an alphanumeric name in /etc/hosts
  931.     X        */
  932.     X        DPRINTF((stderr,"%s: got hostname\n",pgmname));
  933.     X        sock.sin_family=host->h_addrtype;
  934.     X        bcopy(host->h_addr,(caddr_t)&sock.sin_addr,host->h_length);
  935.     X        name=host->h_name;
  936.     X        }
  937.     X    else if ((sock.sin_addr.s_addr=inet_addr(hostname))!=-1)
  938.     X        {
  939.     X        /*
  940.     X        ** hostname is a numeric IP address
  941.     X        */
  942.     X        DPRINTF((stderr,"%s: got IP address\n",pgmname));
  943.     X        sock.sin_family=AF_INET;
  944.     X        name=hostname;
  945.     X        }
  946.     X    else
  947.     X        /*
  948.     X        ** hostname is not anything useful
  949.     X        */
  950.     X        fatal(sock.sin_addr.s_addr,"establish hostname failed",LPD_ABORT);
  951.     X#ifndef BRIDGE
  952.     X    sock.sin_port=srvc->s_port;
  953.     X#else
  954.     X    sock.sin_port= htons ( atoi (port));
  955.     X    DPRINTF ((stderr,"%s:  tcp port %d\n",pgmname, atoi (port) ));  
  956.     X#endif
  957.     X    if ((netfd=socket(AF_INET,SOCK_STREAM,0,0))<0)
  958.     X        fatal(netfd,"establish socket failed",LPD_ABORT);
  959.     X    if ((rc=connect(netfd,(caddr_t)&sock,sizeof(sock),0))<0)
  960.     X        fatal(rc,"establish connect failed",LPD_ABORT);
  961.     X    DPRINTF((stderr,"%s: establish host=%s, socket=%d\n",pgmname,name,netfd));
  962.     X    return(netfd);
  963.     X    }
  964.     X
  965.     X/*
  966.     X**    Handshake: Given a TCP/IP/TELNET connection to an Annex,
  967.     X**    carry out handshaking necessary to connect to the specified
  968.     X**    serial port. This is clearly kludgy, and should be replaced
  969.     X**    with Encore's Annex R4.0.
  970.     X**
  971.     X*/
  972.     Xvoid
  973.     Xhandshake(netfd,port)
  974.     Xint netfd;
  975.     Xchar *port;
  976.     X    {
  977.     X    int rc;
  978.     X
  979.     X    DPRINTF((stderr,"%s: handshake fd=%d, port=%s\n",pgmname,netfd,port));
  980.     X#ifndef BRIDGE
  981.     X    transmit(netfd,"\r",1);
  982.     X    trigger(netfd,':');
  983.     X    trigger(netfd,':');
  984.     X    transmit(netfd,port,strlen(port));
  985.     X    transmit(netfd,"\r",1);
  986.     X    trigger(netfd,'\n');
  987.     X    trigger(netfd,'\n');
  988.     X#endif
  989.     X    }
  990.     X
  991.     X/*
  992.     X**    Trigger: Scan the data from a specified file descriptor until
  993.     X**    the given trigger character is encountered. Hey, is this kludgey
  994.     X**    or what? But it keeps handshake and the comm server synchronized
  995.     X**    (providing no characters are lost), and keeps pscomm from seeing
  996.     X**    any of the prompts from the annex. Both trigger and handshake
  997.     X**    will be obsolesced by Encore's Annex R4.0, which has a better
  998.     X**    reverse telnet mechanism.
  999.     X*/
  1000.     Xvoid
  1001.     Xtrigger(fd,ch)
  1002.     Xint fd;
  1003.     Xchar ch;
  1004.     X    {
  1005.     X    int count;
  1006.     X    char buf;
  1007.     X
  1008.     X    do
  1009.     X        {
  1010.     X        if ((count=receive(fd,&buf,1))!=1)
  1011.     X            fatal(count,"trigger receive would block",LPD_ABORT);
  1012.     X#ifdef DEBUG
  1013.     X        if (debugon) putc(buf,stderr);
  1014.     X#endif
  1015.     X        }
  1016.     X    while (buf!=ch);
  1017.     X    }
  1018.     X
  1019.     X/*
  1020.     X**    Attach: Given a connection to a particular serial port on an
  1021.     X**    terminal server, invoke an appropriate printer filter to handle the
  1022.     X**    input/output.
  1023.     X*/
  1024.     Xint
  1025.     Xattach(filter,argc,argv,prtfd)
  1026.     Xint argc,prtfd;
  1027.     Xchar *filter,**argv;
  1028.     X    {
  1029.     X    int rc,pid;
  1030.     X
  1031.     X    if ((pid=fork())<0)
  1032.     X        fatal(pid,"attach fork failed",LPD_ABORT);
  1033.     X    else
  1034.     X        if (pid)
  1035.     X            {
  1036.     X            /*
  1037.     X            ** Child owns the prtfd now.
  1038.     X            */
  1039.     X            close(prtfd);
  1040.     X            DPRINTF((stderr,"%s: attach filter=%s, prtfd=%d, pid=%d\n",pgmname,filter,prtfd,pid));
  1041.     X#ifdef DEBUG
  1042.     X            if (debugon) pargs(argc,argv);
  1043.     X#endif
  1044.     X            return(pid);
  1045.     X            }
  1046.     X        else
  1047.     X            {
  1048.     X            /*
  1049.     X            ** stdout gets connected to the tty end of pty
  1050.     X            ** so pscomm sees a tty devices as its output.
  1051.     X            ** stdin remains connected to lpd output.
  1052.     X            */
  1053.     X            close(1);
  1054.     X            if ((rc=dup2(prtfd,1))==-1)
  1055.     X                fatal(rc,"attach dup2 failed",LPD_ABORT);
  1056.     X            if ((rc=execvp(filter,argv))==-1)
  1057.     X                fatal(rc,"attach execvp failed",LPD_ABORT);
  1058.     X            /*
  1059.     X            ** Never reached.
  1060.     X            */
  1061.     X            }
  1062.     X    }
  1063.     X
  1064.     X/*
  1065.     X**    Rendezvous: waits for the child process (the true printer
  1066.     X**    filter) to complete.
  1067.     X*/
  1068.     Xvoid
  1069.     Xrendezvous(filterpid,prodpid,conspid)
  1070.     Xint filterpid,prodpid,conspid;
  1071.     X    {
  1072.     X    int wpid,rc;
  1073.     X    union wait status;
  1074.     X
  1075.     X    do
  1076.     X        wpid=wait(&status);
  1077.     X    while ((wpid!=filterpid)&&(wpid!=-1));
  1078.     X    if (wpid==-1)
  1079.     X        fatal(wpid,"rendezvous wait failed",LPD_ABORT);
  1080.     X    rc=status.w_retcode;
  1081.     X    if (rc!=LPD_OK)
  1082.     X        fatal(rc,"rendezvous filter failed",rc);
  1083.     X    DPRINTF((stderr,"%s: rendezvous wpid=%d, retcode=%d\n",pgmname,wpid,rc));
  1084.     X    /*
  1085.     X    ** These may have already returned, in which case the kill
  1086.     X    ** returns an error we can safely ignore.
  1087.     X    */
  1088.     X    kill(prodpid,SIGTERM);
  1089.     X    kill(conspid,SIGTERM);
  1090.     X    }
  1091.     X
  1092.     X/*
  1093.     X**    Acquire: open a device and return the file descriptor.
  1094.     X*/
  1095.     Xint
  1096.     Xacquire(dev)
  1097.     Xchar *dev;
  1098.     X    {
  1099.     X    int fd;
  1100.     X
  1101.     X    if ((fd=open(dev,O_RDWR))==-1)
  1102.     X        fatal(fd,"acquire open failed",LPD_ABORT);
  1103.     X    DPRINTF((stderr,"%s: acquire dev=%s, fd=%d\n",pgmname,dev,fd));
  1104.     X    return(fd);
  1105.     X    }
  1106.     X
  1107.     X/*
  1108.     X**    Spool: set up the net and pty connections and fork off
  1109.     X**    children to do the actual work.
  1110.     X*/
  1111.     Xvoid
  1112.     Xspool(netfd,ptyfd,prodpid,conspid)
  1113.     Xint netfd,ptyfd,*prodpid,*conspid;
  1114.     X    {
  1115.     X    int rc;
  1116.     X
  1117.     X    if ((*conspid=fork())<0)
  1118.     X        fatal(*conspid,"spool consumer fork failed",LPD_ABORT);
  1119.     X    if (!*conspid)
  1120.     X        {
  1121.     X        rc=process(netfd,ptyfd);
  1122.     X        /*
  1123.     X        ** Release fds now that consumer is complete.
  1124.     X        */
  1125.     X        close(netfd);
  1126.     X        close(ptyfd);
  1127.     X        exit(rc);
  1128.     X        }
  1129.     X    DPRINTF((stderr,"%s: spool %d->%d=%d\n",pgmname,netfd,ptyfd,*conspid));
  1130.     X    if ((*prodpid=fork())<0)
  1131.     X        fatal(*prodpid,"spool producer fork failed",LPD_ABORT);
  1132.     X    if (!*prodpid)
  1133.     X        {
  1134.     X        rc=process(ptyfd,netfd);
  1135.     X        /*
  1136.     X        ** Release fds now that producer is complete.
  1137.     X        */
  1138.     X        close(ptyfd);
  1139.     X        close(netfd);
  1140.     X        exit(rc);
  1141.     X        }
  1142.     X    /*
  1143.     X    ** Producer and consumer children own the fds now.
  1144.     X    */
  1145.     X    close(ptyfd);
  1146.     X    close(netfd);
  1147.     X    DPRINTF((stderr,"%s: spool %d->%d=%d\n",pgmname,ptyfd,netfd,*prodpid));
  1148.     X    }
  1149.     X
  1150.     X/*
  1151.     X**    Process: copy from input fd to output fd until end of file.
  1152.     X*/
  1153.     Xint
  1154.     Xprocess(infd,outfd)
  1155.     X    {
  1156.     X    int len;
  1157.     X    char buf[BUFFER+1];
  1158.     X
  1159.     X    do
  1160.     X        if ((len=receive(infd,buf,sizeof(buf)))>0)
  1161.     X            {
  1162.     X            transmit(outfd,buf,len);
  1163.     X#ifdef DUMP
  1164.     X            if (dumpon)
  1165.     X                {
  1166.     X                buf[len]='\0';
  1167.     X                fputs(buf,stderr);
  1168.     X                }
  1169.     X#endif
  1170.     X            }
  1171.     X    while (len>0);
  1172.     X    DPRINTF((stderr,"%s: process %d->%d=%d\n",pgmname,infd,outfd,len));
  1173.     X    return(len);
  1174.     X    }
  1175.     X
  1176.     X/*
  1177.     X**    Transmit: send a buffer of a given length to a
  1178.     X**    specified file descriptor.
  1179.     X*/
  1180.     Xvoid
  1181.     Xtransmit(fd,buf,len)
  1182.     Xint fd,len;
  1183.     Xchar *buf;
  1184.     X    {
  1185.     X    int count;
  1186.     X
  1187.     X    while (len>0)
  1188.     X        if ((count=write(fd,buf,len))<0)
  1189.     X            {
  1190.     X            if (errno!=EWOULDBLOCK)
  1191.     X                fatal(count,"transmit write failed",LPD_ABORT);
  1192.     X            }
  1193.     X        else
  1194.     X            {
  1195.     X            buf+=count;
  1196.     X            len-=count;
  1197.     X            }
  1198.     X    }
  1199.     X
  1200.     X/*
  1201.     X**    Receive: Receive a specified amount of data from a given
  1202.     X**    file descriptor and place it in the specied buffer.
  1203.     X*/
  1204.     Xint
  1205.     Xreceive(fd,buf,len)
  1206.     Xint fd,len;
  1207.     Xchar *buf;
  1208.     X    {
  1209.     X    int count;
  1210.     X
  1211.     X    if (len<=0)
  1212.     X        return(len);
  1213.     X    if ((count=read(fd,buf,len))<0)
  1214.     X        {
  1215.     X        if (errno!=EWOULDBLOCK)
  1216.     X            fatal(count,"receive read failed",LPD_ABORT);
  1217.     X        }
  1218.     X    else
  1219.     X        if (count>len)
  1220.     X            fatal(count,"receive read overflow",LPD_ABORT);
  1221.     X    return(count);
  1222.     X    }
  1223.     X
  1224.     X/*
  1225.     X**    Bailout: handle interrupts while attempting to exit
  1226.     X**    as gracefully and politely as possible.
  1227.     X*/
  1228.     Xvoid
  1229.     Xbailout(rc)
  1230.     Xint rc;
  1231.     X    {
  1232.     X    switch(rc)
  1233.     X        {
  1234.     X    case 1:
  1235.     X        signal(SIGPIPE,SIG_DFL);
  1236.     X        fatal(rc,"broken pipe",LPD_ABORT);
  1237.     X        break;
  1238.     X    case 2:
  1239.     X        signal(SIGINT,SIG_DFL);
  1240.     X        fatal(rc,"aborted",LPD_ABORT);
  1241.     X        break;
  1242.     X    default:
  1243.     X        fatal(rc,"unknown signal",LPD_ABORT);
  1244.     X        }
  1245.     X    }
  1246.     X
  1247.     X/*
  1248.     X**    Fatal: Prints the system error message, prints a user
  1249.     X**    error message, and exits with the specified code.
  1250.     X*/
  1251.     Xvoid
  1252.     Xfatal(rc,msg,xit)
  1253.     Xint rc,xit;
  1254.     Xchar *msg;
  1255.     X    {
  1256.     X    /*
  1257.     X    ** Naively assume that if rc<=0, it's a system call
  1258.     X    ** return, and perror is valid; otherwise, perror is
  1259.     X    ** misleading.
  1260.     X    */
  1261.     X    if (rc<=0)
  1262.     X        perror("annexf");
  1263.     X    fprintf(stderr,"%s: %s (%d)\n",pgmname,msg,rc);
  1264.     X    cleanup();
  1265.     X    exit(xit);
  1266.     X    }
  1267.     X
  1268.     X/*
  1269.     X**    Usage: check argc, and report usage error.
  1270.     X*/
  1271.     Xvoid
  1272.     Xusage(argc)
  1273.     Xint argc;
  1274.     X    {
  1275.     X    if (argc <= 0)
  1276.     X        {
  1277.     X        fprintf(stderr,"usage: %s [-v] [-x] [[-h host [-p port]]|[-d device]] [-t pty tty] [-f filter [args]]\n",pgmname);
  1278.     X        cleanup();
  1279.     X        exit(LPD_ABORT);
  1280.     X        }
  1281.     X    }
  1282.     X
  1283.     X/*
  1284.     X**    Lost: Interrupt service routine which is invoked when
  1285.     X**    a pipe breaks and a connection is lost.
  1286.     X*/
  1287.     Xvoid
  1288.     Xlost()
  1289.     X    {
  1290.     X    longjmp(context,1);
  1291.     X    }
  1292.     X
  1293.     X/*
  1294.     X**    Interrupted: Interrupt service routine which is invoked
  1295.     X**    when a interrupt signal is received from another process
  1296.     X**    (typically the line printer spooler daemon).
  1297.     X*/
  1298.     Xvoid
  1299.     Xinterrupted()
  1300.     X    {
  1301.     X    longjmp(context,2);
  1302.     X    }
  1303.     X
  1304.     X/*
  1305.     X**    Finished: Interrupt service routine which is invoked
  1306.     X**    when the parent receives end of file and signals the
  1307.     X**    child process to terminate.
  1308.     X*/
  1309.     Xvoid
  1310.     Xfinished()
  1311.     X    {
  1312.     X    longjmp(context,3);
  1313.     X    }
  1314.     X
  1315.     X#ifdef DEBUG
  1316.     X/*
  1317.     X**    Pargs: prints argc and argv argument lists for debugging.
  1318.     X*/
  1319.     Xvoid
  1320.     Xpargs(argc,argv)
  1321.     Xint argc;
  1322.     Xchar **argv;
  1323.     X    {
  1324.     X    int nargc;
  1325.     X
  1326.     X    fprintf(stderr,"%s:",pgmname);
  1327.     X    for (nargc=0;argc>0;argc--,nargc++,argv++)
  1328.     X        {
  1329.     X        putc(' ',stderr);
  1330.     X        fputs(*argv,stderr);
  1331.     X        }
  1332.     X    putc('\n',stderr);
  1333.     X    }
  1334.     X#endif
  1335. SHAR_EOF
  1336. if test 16356 -ne "`wc -c < 'servercomm.c'`"
  1337. then
  1338.     echo shar: error transmitting "'servercomm.c'" '(should have been 16356 characters)'
  1339. fi
  1340. fi # end of overwriting check
  1341. #    End of shell archive
  1342. exit 0
  1343.  
  1344.